﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using UniTax.Models;
using Converter = UniTax.Models.Converter;
using System.Web.Script.Serialization;

namespace UniTax.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Приложение UniTax";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Как с нами связаться.";

            return View();
        }

        #region Town

        public ActionResult TownList()
        {
            using (var db = new Models.UniTaxEntities())
            {
                var townList = new TownList
                    {
                        //Выбираем все города
                        Towns = (from t in db.Towns
                                 orderby t.Name
                                 select new TownModel
                                     {
                                         Id = t.Id,
                                         Name = t.Name,
                                         LastUpd = t.LastUpd
                                     }).ToList()
                    };
                return View(townList);
            }
        }

        [Authorize]
        public ActionResult TownCreate()
        {
            using (var db = new Models.UniTaxEntities())
            {
                var model = new TownModel();

                return View(model);
            }
        }

        [Authorize]
        [HttpPost]
        public ActionResult TownCreate(FormCollection formValues)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    using (var db = new UniTaxEntities())
                    {
                        var newTown = new Models.Town()
                        {
                            Name = formValues["Name"]
                        };

                        //Сохраняем новый город в базе и получаем его ID
                        db.Towns.Add(newTown);
                        db.SaveChanges();

                        return RedirectToAction("TownList");
                    }
                }
                ModelState.AddModelError("", "Введенные данные не корректны.");
            }
            catch
            {
                return View();
            }
            return View();
        }

        [Authorize]
        public ActionResult TownDelete(int id)
        {
            using (var db = new UniTaxEntities())
            {
                var town = (db.Towns.Where(t => t.Id == id).Select(t => new TownModel()
                {
                    Id = t.Id,
                    Name = t.Name,
                    LastUpd = t.LastUpd
                })).First();
                return View(town);
            }
        }

        [Authorize]
        [HttpPost]
        public ActionResult TownDelete(int id, FormCollection collection)
        {
            try
            {
                using (var db = new UniTaxEntities())
                {
                    var town = (from t in db.Towns
                                where t.Id == id
                                select t).First();

                    db.Towns.Remove(town);
                    db.SaveChanges();
                    return RedirectToAction("Taxi");
                }
            }
            catch
            {
                return View();
            }
        }

        [Authorize]
        public ActionResult TownEdit(int id)
        {
            using (var db = new UniTaxEntities())
            {
                var town = (db.Towns.Where(t => t.Id == id).Select(t => new TownModel()
                {
                    Id = t.Id,
                    Name = t.Name
                })).First();
                return View(town);
            }
        }

        [Authorize]
        [HttpPost]
        public ActionResult TownEdit(int id, FormCollection collection)
        {
            try
            {
                using (var db = new UniTaxEntities())
                {
                    var town = (from t in db.Towns
                                where t.Id == id
                                select t).First();

                    town.Name = collection["Name"];


                    UpdateModel(town);
                    db.SaveChanges();
                    return RedirectToAction("TownList");
                }
            }
            catch
            {
                return View();
            }
        }

        #endregion

        #region Taxi

        [Authorize(Roles = "Admin")]
        public ActionResult Taxi()
        {
            using (var db = new Models.UniTaxEntities())
            {
                var townList = new TownList
                    {
                        //Выбираем все города
                        Towns = (from t in db.Towns
                                 orderby t.Name
                                 select new TownModel
                                 {
                                     Id = t.Id,
                                     Name = t.Name,
                                     LastUpd = t.LastUpd
                                 }).ToList()
                    };
                return View(townList);
            }
        }

        [Authorize]
        public ActionResult TaxiList(int id)
        {
            using (var db = new Models.UniTaxEntities())
            {
                var taxiList = new TaxiList()
                    {
                        //Выбираем все службы такси
                        Taxis = (from t in db.Taxis
                                 where t.TownId == id
                                 orderby t.Raiting descending
                                 select new TaxiModel
                                     {
                                         Id = t.Id,
                                         Name = t.Name,
                                         TownId = t.TownId,
                                         License = t.License,
                                         Logo = t.Logo,
                                         Raiting = t.Raiting,
                                         ContactName = t.ContactName,
                                         ContactPhones = (from cp in db.ContactPhones
                                                          join tcp in db.Taxi_ContactPhones on cp.Id equals tcp.ContactPhoneId
                                                          join tax in db.Taxis on tcp.TaxiId equals tax.Id
                                                          where tax.Id == t.Id
                                                          select cp),
                                         Functions = (from f in db.Functions
                                                      join tf in db.Taxi_Functions on f.Id equals tf.FunctionId
                                                      join tax in db.Taxis on tf.TaxiId equals tax.Id
                                                      where tax.Id == t.Id
                                                      select f),
                                         Phones = (from p in db.Phones
                                                   join tp in db.Taxi_Phones on p.Id equals tp.PhoneId
                                                   join tax in db.Taxis on tp.TaxiId equals tax.Id
                                                   where tax.Id == t.Id
                                                   select p)
                                     }).ToList(),
                        Town = (from t1 in db.Towns
                                where t1.Id == id
                                select new TownModel()
                                    {
                                        Id = t1.Id,
                                        Name = t1.Name,
                                        LastUpd = t1.LastUpd
                                    }).First()
                    };
                return View(taxiList);
            }
        }

        [Authorize]
        public ActionResult TaxiDetails(int id)
        {
            using (var db = new UniTaxEntities())
            {
                var taxi = (db.Taxis.Where(t => t.Id == id).Select(t => new TaxiModel()
                {
                    Id = t.Id,
                    Name = t.Name,
                    TownId = t.TownId,
                    License = t.License,
                    Logo = t.Logo,
                    LogoMimeType = t.LogoMimeType,
                    Raiting = t.Raiting,
                    ContactName = t.ContactName,
                    ContactPhones = (from cp in db.ContactPhones
                                     join tcp in db.Taxi_ContactPhones on cp.Id equals tcp.ContactPhoneId
                                     join tax in db.Taxis on tcp.TaxiId equals tax.Id
                                     where tax.Id == t.Id
                                     select cp),
                    Functions = (from f in db.Functions
                                 join tf in db.Taxi_Functions on f.Id equals tf.FunctionId
                                 join tax in db.Taxis on tf.TaxiId equals tax.Id
                                 where tax.Id == t.Id
                                 select f),
                    Phones = (from p in db.Phones
                              join tp in db.Taxi_Phones on p.Id equals tp.PhoneId
                              join tax in db.Taxis on tp.TaxiId equals tax.Id
                              where tax.Id == t.Id
                              select p)
                })).First();
                return View(taxi);
            }
        }

        [Authorize]
        public ActionResult TaxiCreate(int townId)
        {
            using (var db = new Models.UniTaxEntities())
            {
                var taxi = new TaxiModel
                    {
                        TownId = townId,
                        License = DateTime.Now.Date
                    };
                taxi.Town = (db.Towns.Where(t => t.Id == townId)
                                .Select(t => new TownModel() { Id = t.Id, Name = t.Name, LastUpd = t.LastUpd })).FirstOrDefault();
                taxi.Functions = (from f in db.Functions
                                  select f).ToList();

                ViewBag.Date = String.Format("{0}/{1}/{2}", taxi.License.Day, taxi.License.Month, taxi.License.Year);
                return View(taxi);
            }
        }

        [Authorize]
        [HttpPost]
        public ActionResult TaxiCreate(FormCollection formValues, HttpPostedFileBase image)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    using (var db = new UniTaxEntities())
                    {
                        var newTaxi = new Models.Taxi
                            {
                                Name = formValues["Name"],
                                TownId = Convert.ToInt32(formValues["TownId"]),
                                License = Convert.ToDateTime(formValues["License"]),
                                Raiting = Convert.ToInt32(formValues["Raiting"]),
                                ContactName = formValues["ContactName"]
                            };

                        //Добавляем логотип
                        if (image != null)
                        {
                            newTaxi.LogoMimeType = image.ContentType;
                            newTaxi.Logo = new byte[image.ContentLength];
                            image.InputStream.Read(newTaxi.Logo, 0, image.ContentLength);
                        }

                        //Сохраняем новое такси в базе и получаем его ID
                        db.Taxis.Add(newTaxi);
                        db.SaveChanges();

                        //Phones
                        for (var i = 0; i < formValues.AllKeys.Length; i++)
                        {
                            if (formValues.AllKeys[i].Contains("phone_"))//Выбраем записи с телефонами
                                if (!string.IsNullOrEmpty(formValues[i]))
                                {
                                    //Сохраняем новый номер телефона в базе и получаем его ID
                                    var newPhone = new Models.Phone
                                        {
                                            Phone1 = formValues[i]
                                        };
                                    db.Phones.Add(newPhone);
                                    db.SaveChanges();

                                    //Запоминаем номер телефона для данного такси
                                    var newTaxiPhone = new Models.Taxi_Phones
                                        {
                                            PhoneId = newPhone.Id,
                                            TaxiId = newTaxi.Id
                                        };
                                    db.Taxi_Phones.Add(newTaxiPhone);
                                    db.SaveChanges();
                                }
                        }

                        //ContactPhones
                        for (var i = 0; i < formValues.AllKeys.Length; i++)
                        {
                            if (formValues.AllKeys[i].Contains("contactPhone_"))//Выбраем записи с контактными телефонами
                                if (!string.IsNullOrEmpty(formValues[i]))
                                {
                                    //Сохраняем новый номер телефона в базе и получаем его ID
                                    var newContactPhone = new Models.ContactPhone
                                    {
                                        Phone = formValues[i]
                                    };
                                    db.ContactPhones.Add(newContactPhone);
                                    db.SaveChanges();

                                    //Запоминаем номер телефона для данного такси
                                    var newTaxiContactPhone = new Models.Taxi_ContactPhones
                                    {
                                        ContactPhoneId = newContactPhone.Id,
                                        TaxiId = newTaxi.Id
                                    };
                                    db.Taxi_ContactPhones.Add(newTaxiContactPhone);
                                    db.SaveChanges();
                                }
                        }

                        //Functions
                        for (var i = 0; i < formValues.AllKeys.Length; i++)
                        {
                            if (formValues.AllKeys[i].Contains("func_"))//Выбраем записи с функциями
                                if (!string.IsNullOrEmpty(formValues[i]))
                                {
                                    switch (formValues.AllKeys[i])
                                    {
                                        case "func_1":
                                            {
                                                if (formValues[i] == "true,false")
                                                {
                                                    //Запоминаем функцию для данного такси
                                                    var newTaxiFunction = new Models.Taxi_Functions()
                                                    {
                                                        FunctionId = 1,
                                                        TaxiId = newTaxi.Id
                                                    };
                                                    db.Taxi_Functions.Add(newTaxiFunction);
                                                    db.SaveChanges();
                                                }
                                                break;
                                            }
                                        case "func_2":
                                            {
                                                if (formValues[i] == "true,false")
                                                {
                                                    //Запоминаем функцию для данного такси
                                                    var newTaxiFunction = new Models.Taxi_Functions()
                                                    {
                                                        FunctionId = 2,
                                                        TaxiId = newTaxi.Id
                                                    };
                                                    db.Taxi_Functions.Add(newTaxiFunction);
                                                    db.SaveChanges();
                                                }
                                                break;
                                            }
                                        case "func_3":
                                            {
                                                if (formValues[i] == "true,false")
                                                {
                                                    //Запоминаем функцию для данного такси
                                                    var newTaxiFunction = new Models.Taxi_Functions()
                                                    {
                                                        FunctionId = 3,
                                                        TaxiId = newTaxi.Id
                                                    };
                                                    db.Taxi_Functions.Add(newTaxiFunction);
                                                    db.SaveChanges();
                                                }
                                                break;
                                            }
                                        case "func_4":
                                            {
                                                if (formValues[i] == "true,false")
                                                {
                                                    //Запоминаем функцию для данного такси
                                                    var newTaxiFunction = new Models.Taxi_Functions()
                                                    {
                                                        FunctionId = 4,
                                                        TaxiId = newTaxi.Id
                                                    };
                                                    db.Taxi_Functions.Add(newTaxiFunction);
                                                    db.SaveChanges();
                                                }
                                                break;
                                            }
                                        case "func_5":
                                            {
                                                if (formValues[i] == "true,false")
                                                {
                                                    //Запоминаем функцию для данного такси
                                                    var newTaxiFunction = new Models.Taxi_Functions()
                                                    {
                                                        FunctionId = 5,
                                                        TaxiId = newTaxi.Id
                                                    };
                                                    db.Taxi_Functions.Add(newTaxiFunction);
                                                    db.SaveChanges();
                                                }
                                                break;
                                            }

                                    }
                                }
                        }

                        return RedirectToAction("TaxiList", new { id = newTaxi.TownId });
                    }
                }
                ModelState.AddModelError("", "Введенные данные не корректны.");
            }
            catch
            {
                return View();
            }
            return View();
        }

        [Authorize]
        public ActionResult TaxiDelete(int id)
        {
            using (var db = new UniTaxEntities())
            {
                var taxi = (db.Taxis.Where(t => t.Id == id).Select(t => new TaxiModel()
                    {
                        Id = t.Id,
                        Name = t.Name,
                        TownId = t.TownId,
                        License = t.License,
                        Logo = t.Logo,
                        Raiting = t.Raiting,
                        ContactName = t.ContactName,
                        ContactPhones = (from cp in db.ContactPhones
                                         join tcp in db.Taxi_ContactPhones on cp.Id equals tcp.ContactPhoneId
                                         join tax in db.Taxis on tcp.TaxiId equals tax.Id
                                         where tax.Id == t.Id
                                         select cp),
                        Functions = (from f in db.Functions
                                     join tf in db.Taxi_Functions on f.Id equals tf.FunctionId
                                     join tax in db.Taxis on tf.TaxiId equals tax.Id
                                     where tax.Id == t.Id
                                     select f),
                        Phones = (from p in db.Phones
                                  join tp in db.Taxi_Phones on p.Id equals tp.PhoneId
                                  join tax in db.Taxis on tp.TaxiId equals tax.Id
                                  where tax.Id == t.Id
                                  select p)
                    })).First();
                return View(taxi);
            }
        }

        [Authorize]
        [HttpPost]
        public ActionResult TaxiDelete(int id, FormCollection collection)
        {
            try
            {
                using (var db = new UniTaxEntities())
                {
                    var taxi = (from t in db.Taxis
                                where t.Id == id
                                select t).First();

                    db.Taxis.Remove(taxi);
                    db.SaveChanges();
                    return RedirectToAction("TaxiList", new { id = taxi.TownId });
                }
            }
            catch
            {
                return View();
            }
        }

        [Authorize]
        public ActionResult TaxiEdit(int id)
        {
            using (var db = new UniTaxEntities())
            {
                var taxi = (db.Taxis.Where(t => t.Id == id).Select(t => new TaxiModel()
                {
                    Id = t.Id,
                    Name = t.Name,
                    TownId = t.TownId,
                    License = t.License,
                    Logo = t.Logo,
                    Raiting = t.Raiting,
                    ContactName = t.ContactName,
                    ContactPhones = (from cp in db.ContactPhones
                                     join tcp in db.Taxi_ContactPhones on cp.Id equals tcp.ContactPhoneId
                                     join tax in db.Taxis on tcp.TaxiId equals tax.Id
                                     where tax.Id == t.Id
                                     select cp),
                    Functions = (from f in db.Functions
                                 join tf in db.Taxi_Functions on f.Id equals tf.FunctionId
                                 join tax in db.Taxis on tf.TaxiId equals tax.Id
                                 where tax.Id == t.Id
                                 select f),
                    Phones = (from p in db.Phones
                              join tp in db.Taxi_Phones on p.Id equals tp.PhoneId
                              join tax in db.Taxis on tp.TaxiId equals tax.Id
                              where tax.Id == t.Id
                              select p),
                    AllFunctions = (from f in db.Functions
                                    select f)
                })).First();

                ViewBag.Date = String.Format("{0}/{1}/{2}", taxi.License.Day, taxi.License.Month, taxi.License.Year);
                return View(taxi);
            }
        }

        [Authorize]
        [HttpPost]
        public ActionResult TaxiEdit(int id, FormCollection collection)
        {
            try
            {
                using (var db = new UniTaxEntities())
                {
                    var taxi = (from t in db.Taxis
                                where t.Id == id
                                select t).First();


                    taxi.Name = collection["Name"];
                    taxi.TownId = Convert.ToInt32(collection["TownId"]);
                    taxi.License = Convert.ToDateTime(collection["License"]);
                    /*if (collection["Logo"] != null)
                        taxi.Logo = Converter.ToArrayOfByte(collection["Logo"]);*/
                    taxi.Raiting = Convert.ToInt32(collection["Raiting"]);
                    taxi.ContactName = collection["ContactName"];

                    #region Удаление телефонов
                    for (var i = 0; i < collection.AllKeys.Length; i++)
                    {
                        if (collection.AllKeys[i].Contains("phoneCheck_")) //Выбраем записи с телефонами отмеченными для удаления
                            if (!string.IsNullOrEmpty(collection[i]))
                            {
                                if (collection[i] == "true,false")
                                {
                                    var identifier = Convert.ToInt32(collection.AllKeys[i].Split('_')[1]);

                                    //удаление связи такси-телефон
                                    var taxiPhoneToDel = (from tp in db.Taxi_Phones
                                                          where (tp.PhoneId == identifier &
                                                                tp.TaxiId == id)
                                                          select tp).First();
                                    db.Taxi_Phones.Remove(taxiPhoneToDel);
                                    db.SaveChanges();

                                    //удаление телефона
                                    var phoneToDel = (from p in db.Phones
                                                      where p.Id == identifier
                                                      select p).First();
                                    db.Phones.Remove(phoneToDel);
                                    db.SaveChanges();
                                }

                            }

                        if (collection.AllKeys[i].Contains("contactPhoneCheck_")) //Выбраем записи с телефонами отмеченными для удаления
                            if (!string.IsNullOrEmpty(collection[i]))
                            {
                                if (collection[i] == "true,false")
                                {
                                    var identifier = Convert.ToInt32(collection.AllKeys[i].Split('_')[1]);

                                    //удаление связи такси-контактный телефон
                                    var taxiContacPhoneToDel = (from tcp in db.Taxi_ContactPhones
                                                                where (tcp.ContactPhoneId == identifier &
                                                            tcp.TaxiId == id)
                                                                select tcp).First();
                                    db.Taxi_ContactPhones.Remove(taxiContacPhoneToDel);
                                    db.SaveChanges();

                                    //удаление телефона
                                    var contactPhoneToDel = (from cp in db.ContactPhones
                                                             where cp.Id == identifier
                                                             select cp).First();
                                    db.ContactPhones.Remove(contactPhoneToDel);
                                    db.SaveChanges();
                                }

                            }

                    }
                    #endregion

                    #region Удаление функций
                    var funcToDel = (from f in db.Taxi_Functions
                                     where f.TaxiId == id
                                     select f);
                    foreach (var item in funcToDel)
                    {
                        db.Taxi_Functions.Remove(item);
                    }
                    db.SaveChanges();
                    #endregion

                    for (var i = 0; i < collection.AllKeys.Length; i++)
                    {
                        #region Добавление телефона
                        if (collection.AllKeys[i].Contains("phone_"))//Выбраем записи с телефонами
                            if (!string.IsNullOrEmpty(collection[i]))
                            {
                                //Сохраняем новый номер телефона в базе и получаем его ID
                                var newPhone = new Models.Phone
                                {
                                    Phone1 = collection[i]
                                };
                                db.Phones.Add(newPhone);
                                db.SaveChanges();

                                //Запоминаем номер телефона для данного такси
                                var newTaxiPhone = new Models.Taxi_Phones
                                {
                                    PhoneId = newPhone.Id,
                                    TaxiId = taxi.Id
                                };
                                db.Taxi_Phones.Add(newTaxiPhone);
                                db.SaveChanges();
                            }
                        #endregion

                        #region Добавление контактного телефона
                        if (collection.AllKeys[i].Contains("contactPhone_"))//Выбраем записи с контактными телефонами
                            if (!string.IsNullOrEmpty(collection[i]))
                            {
                                //Сохраняем новый номер телефона в базе и получаем его ID
                                var newContactPhone = new Models.ContactPhone
                                {
                                    Phone = collection[i]
                                };
                                db.ContactPhones.Add(newContactPhone);
                                db.SaveChanges();

                                //Запоминаем номер телефона для данного такси
                                var newTaxiContactPhone = new Models.Taxi_ContactPhones
                                {
                                    ContactPhoneId = newContactPhone.Id,
                                    TaxiId = taxi.Id
                                };
                                db.Taxi_ContactPhones.Add(newTaxiContactPhone);
                                db.SaveChanges();
                            }
                        #endregion

                        //Функции
                        if (collection.AllKeys[i].Contains("func_"))//Выбраем записи с функциями
                            if (!string.IsNullOrEmpty(collection[i]))
                            {
                                #region Добавление функций
                                switch (collection.AllKeys[i])
                                {
                                    case "func_1":
                                        {
                                            if (collection[i] == "true,false")
                                            {
                                                //Запоминаем функцию для данного такси
                                                var newTaxiFunction = new Models.Taxi_Functions()
                                                {
                                                    FunctionId = 1,
                                                    TaxiId = taxi.Id
                                                };
                                                db.Taxi_Functions.Add(newTaxiFunction);
                                                db.SaveChanges();
                                            }
                                            break;
                                        }
                                    case "func_2":
                                        {
                                            if (collection[i] == "true,false")
                                            {
                                                //Запоминаем функцию для данного такси
                                                var newTaxiFunction = new Models.Taxi_Functions()
                                                {
                                                    FunctionId = 2,
                                                    TaxiId = taxi.Id
                                                };
                                                db.Taxi_Functions.Add(newTaxiFunction);
                                                db.SaveChanges();
                                            }
                                            break;
                                        }
                                    case "func_3":
                                        {
                                            if (collection[i] == "true,false")
                                            {
                                                //Запоминаем функцию для данного такси
                                                var newTaxiFunction = new Models.Taxi_Functions()
                                                {
                                                    FunctionId = 3,
                                                    TaxiId = taxi.Id
                                                };
                                                db.Taxi_Functions.Add(newTaxiFunction);
                                                db.SaveChanges();
                                            }
                                            break;
                                        }
                                    case "func_4":
                                        {
                                            if (collection[i] == "true,false")
                                            {
                                                //Запоминаем функцию для данного такси
                                                var newTaxiFunction = new Models.Taxi_Functions()
                                                {
                                                    FunctionId = 4,
                                                    TaxiId = taxi.Id
                                                };
                                                db.Taxi_Functions.Add(newTaxiFunction);
                                                db.SaveChanges();
                                            }
                                            break;
                                        }
                                    case "func_5":
                                        {
                                            if (collection[i] == "true,false")
                                            {
                                                //Запоминаем функцию для данного такси
                                                var newTaxiFunction = new Models.Taxi_Functions()
                                                {
                                                    FunctionId = 5,
                                                    TaxiId = taxi.Id
                                                };
                                                db.Taxi_Functions.Add(newTaxiFunction);
                                                db.SaveChanges();
                                            }
                                            break;
                                        }

                                }
                                #endregion
                            }
                    }


                    UpdateModel(taxi);
                    db.SaveChanges();
                    return RedirectToAction("TaxiList", new { id = Convert.ToInt32(collection["TownId"]) });
                }
            }
            catch
            {
                return View();
            }
        }

        [Authorize]
        public ActionResult UploadImage()
        {
            //Just to distinguish between ajax request (for: modal dialog) and normal request
            if (Request.IsAjaxRequest())
            {
                return PartialView();
            }

            return View();
        }

        [HttpPost]
        [Authorize]
        public ActionResult UploadImage(UploadImageModel model)
        {
            //Check if all simple data annotations are valid
            if (ModelState.IsValid)
            {
                //Prepare the needed variables
                Bitmap original = null;
                var name = "newimagefile";
                var errorField = string.Empty;

                if (model.File != null) // model.IsFile
                {
                    errorField = "File";
                    name = /*Path.GetFileNameWithoutExtension(model.File.FileName);*/ Guid.NewGuid().ToString();
                    original = Bitmap.FromStream(model.File.InputStream) as Bitmap;
                }

                //If we had success so far
                if (original != null)
                {
                    var img = CreateImage(original, model.X, model.Y, model.Width, model.Height);

                    //Demo purposes only - save image in the file system
                    var fn = Server.MapPath("~/Content/logo/" + name + ".png");
                    img.Save(fn, System.Drawing.Imaging.ImageFormat.Png);

                    //Redirect to index
                    return RedirectToAction("Taxi","Home");
                }
                else //Otherwise we add an error and return to the (previous) view with the model data
                    ModelState.AddModelError(errorField, "Your upload did not seem valid. Please try again using only correct images!");
            }

            return View(model);
        }

        #endregion

        #region Interaction with the application

        [HttpPost]
        [AllowCrossSiteJson]
        public JsonResult Init(string os, string version)
        {
            using (var db = new Models.UniTaxEntities())
            {
                var app = new Models.Application()
                {
                    OSType = os,
                    OSVersion = version,
                    DateInit = DateTime.Today,
                    DateLastActive = DateTime.Now
                };
                db.Applications.Add(app);
                db.SaveChanges();

                return Json(new { Id = app.Id }, JsonRequestBehavior.AllowGet);
            }

        }


        [HttpPost]
        [AllowCrossSiteJson]
        public JsonResult Update(string townId, string lastUpd, string appId)
        {
            try
            {
                var localTownId = Convert.ToInt32(townId);
                var localLastUpd = Convert.ToDateTime(lastUpd);
                var localAppId = Convert.ToInt32(appId);

                using (var db = new Models.UniTaxEntities())
                {
                    if (localTownId == 0) //Для загрузки списка городов (при первом запуске)
                    {
                        var towns = (from t in db.Towns
                                     select new
                                     {
                                         Id = t.Id,
                                         Name = t.Name,
                                         LastUpd = t.LastUpd
                                     }).ToList();

                        return Json(towns, JsonRequestBehavior.AllowGet);
                    }
                    else //Обновление списка такси по выбранному городу
                    {

                        //Добавляем информацию об активности приложения в базу
                        var app = (from ap in db.Applications
                                   where ap.Id == localAppId
                                   select ap).First();
                        if (app != null)
                        {
                            app.TownSelect = localTownId;
                            app.DateLastActive = DateTime.Now;
                            db.Applications.Add(app);
                            db.SaveChanges();
                        }

                        //Проверяем дату обновления
                        var town = (from t in db.Towns
                                    where t.Id == localTownId
                                    select new
                                    {
                                        Id = t.Id,
                                        Name = t.Name,
                                        LastUpd = t.LastUpd
                                    }).First();

                        if (town.LastUpd > localLastUpd)
                        {
                            //Выбираем все службы такси
                            var taxis = (from t in db.Taxis
                                         where t.TownId == localTownId
                                         select new
                                             {
                                                 Id = t.Id,
                                                 Name = t.Name,
                                                 TownId = t.TownId,
                                                 License = t.License,
                                                 Logo = t.Logo,
                                                 Raiting = t.Raiting,
                                                 ContactName = t.ContactName,
                                                 Town = (from city in db.Towns
                                                         where city.Id == localTownId
                                                         select new
                                                         {
                                                             Id = city.Id,
                                                             Name = city.Name,
                                                             LastUpd = city.LastUpd
                                                         }),
                                                 ContactPhones = (from cp in db.ContactPhones
                                                                  join tcp in db.Taxi_ContactPhones on cp.Id equals
                                                                      tcp.ContactPhoneId
                                                                  join tax in db.Taxis on tcp.TaxiId equals tax.Id
                                                                  where tax.Id == t.Id
                                                                  select new
                                                                      {
                                                                          Id = cp.Id,
                                                                          Phone = cp.Phone
                                                                      }),
                                                 Functions = (from f in db.Functions
                                                              join tf in db.Taxi_Functions on f.Id equals tf.FunctionId
                                                              join tax in db.Taxis on tf.TaxiId equals tax.Id
                                                              where tax.Id == t.Id
                                                              select new
                                                              {
                                                                  Id = f.Id,
                                                                  Name = f.Name
                                                              }),
                                                 Phones = (from p in db.Phones
                                                           join tp in db.Taxi_Phones on p.Id equals tp.PhoneId
                                                           join tax in db.Taxis on tp.TaxiId equals tax.Id
                                                           where tax.Id == t.Id
                                                           select new
                                                           {
                                                               Id = p.Id,
                                                               Phone1 = p.Phone1
                                                           })
                                             }).ToList();

                            return Json(new { town = town, taxis = taxis }, JsonRequestBehavior.AllowGet);
                        }
                        else
                        {
                            return null;
                        }
                    }
                }

            }
            catch (Exception)
            {
                return null;
            }

        }

        #endregion

        #region Helper
        /// <summary>
        /// Creates a small image out of a larger image.
        /// </summary>
        /// <param name="original">The original image which should be cropped (will remain untouched).</param>
        /// <param name="x">The value where to start on the x axis.</param>
        /// <param name="y">The value where to start on the y axis.</param>
        /// <param name="width">The width of the final image.</param>
        /// <param name="height">The height of the final image.</param>
        /// <returns>The cropped image.</returns>
        Bitmap CreateImage(Bitmap original, int x, int y, int width, int height)
        {
            var img = new Bitmap(width, height);

            using (var g = Graphics.FromImage(img))
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(original, new Rectangle(0, 0, width, height), x, y, width, height, GraphicsUnit.Pixel);
            }

            return img;
        }
        #endregion
    }
}